package cn.shop.utils;


import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.function.Supplier;

import static cn.shop.utils.Utils.isNotEmpty;

/**
 * @author Zhy
 */
@SuppressWarnings("unused")
public class NumberUtils {
	
	/**
	 * 如果输入字符串可以转为Integer，返回转成的Integer，否则返回null。
	 * 
	 * @param value 要转换的字符串
	 * @return 如果成功，转换成的Integer，否则null
	 */
	public static Integer toInt(String value) {
		Integer result = null;
		if (isNotEmpty(value)) {
			try {
				result = new BigDecimal(value).intValueExact();
			} catch (Exception e) {
				// ignore
			}
		}
		return result;
	}
	
	/**
	 * 如果supplier提供的字符串可以转成Integer，返回转成的Integer，否则返回null。
	 * 
	 * @param supplier 提供要转换的字符串
	 * @return 如果成功，转换成的Integer，否则null
	 */
	public static Integer toInt(Supplier<String> supplier) {
		return toInt(supplier.get());
	}
	
	/**
	 * 如果输入字符串可以转为int，返回转成的int，否则返回0。
	 * 
	 * @param value 要转换的字符串
	 * @return 如果成功，转换成的int，否则0
	 */
	public static int toIntSafe(String value) {
		int result = 0;
		if (isNotEmpty(value)) {
			try {
				result = new BigDecimal(value).intValueExact();
			} catch (Exception e) {
				// ignore
			}
		}
		return result;
	}
	
	/**
	 * 如果supplier提供的字符串可以转成int，返回转成的int，否则返回0。
	 * 
	 * @param supplier 提供要转换的字符串
	 * @return 如果成功，转换成的int，否则0
	 */
	public static int toIntSafe(Supplier<String> supplier) {
		return toIntSafe(supplier.get());
	}
	
	/**
	 * 如果value不是null，返回其字符串表示，否则返回null。
	 * 
	 * @param value 要转换的数
	 * @return 如果成功，value转成的字符串，否则null
	 */
	public static String fromInt(Integer value) {
		return value == null ? null : value.toString();
	}

	/**
	 * 如果输入字符串可以转为Long，返回转成的Long，否则返回null。
	 * 
	 * @param value 要转换的字符串
	 * @return 如果成功，转换成的Long，否则null
	 */
	public static Long toLong(String value) {
		Long result = null;
		if (isNotEmpty(value)) {
			try {
				result = new BigDecimal(value).longValueExact();
			} catch (Exception e) {
				// ignore
			}
		}
		return result;
	}
	
	/**
	 * 如果supplier提供的字符串可以转成Long，返回转成的Long，否则返回null。
	 * 
	 * @param supplier 提供要转换的字符串
	 * @return 如果成功，转换成的Long，否则null
	 */
	public static Long toLong(Supplier<String> supplier) {
		return toLong(supplier.get());
	}
	
	/**
	 * 如果输入字符串可以转为long，返回转成的long，否则返回0。
	 * 
	 * @param value 要转换的字符串
	 * @return 如果成功，转换成的long，否则0
	 */
	public static long toLongSafe(String value) {
		long result = 0;
		if (isNotEmpty(value)) {
			try {
				result = new BigDecimal(value).longValueExact();
			} catch (Exception e) {
				// ignore
			}
		}
		return result;
	}
	
	/**
	 * 如果supplier提供的字符串可以转成long，返回转成的long，否则返回0。
	 * 
	 * @param supplier 提供要转换的字符串
	 * @return 如果成功，转换成的long，否则0
	 */
	public static long toLongSafe(Supplier<String> supplier) {
		return toLongSafe(supplier.get());
	}
	
	/**
	 * 如果value不是null，返回其字符串表示，否则返回null。
	 * 
	 * @param value 要转换的数
	 * @return 如果成功，value转成的字符串，否则null
	 */
	public static String fromLong(Long value) {
		return value == null ? null : value.toString();
	}

	/**
	 * 如果输入字符串可以转成BigDecimal，返回转成的BigDecimal，否则返回null。
	 * 
	 * @param value 要转换的字符串
	 * @return 如果成功，转换成的BigDecimal，否则null
	 */
	public static BigDecimal toDecimal(String value) {
		BigDecimal result = null;
		if (isNotEmpty(value)) {
			try {
				result = new BigDecimal(value);
			} catch (Exception e) {
				// ignore
			}
		}
		return result;
	}

	/**
	 * 如果supplier提供的字符串可以转成BigDecimal，返回转成的BigDecimal，否则返回null。
	 * 
	 * @param supplier 提供需要转换的字符串
	 * @return 如果成功，转换成的BigDecimal，否则null
	 */
	public static BigDecimal toDecimal(Supplier<String> supplier) {
		return toDecimal(supplier.get());
	}
	
	/**
	 * 如果输入数值非null，返回转成的BigDecimal，否则返回null。
	 * 
	 * @param number 要转换的数值
	 * @return 如果数值非null，转换成的BigDecimal，否则null
	 */
	public static BigDecimal toDecimal(Number number) {
		if (number instanceof BigDecimal) {
			return (BigDecimal) number;
		} else if (number instanceof BigInteger) {
			return new BigDecimal((BigInteger) number);
		} else if (number instanceof Long) {
			return BigDecimal.valueOf(number.longValue());
		} else if (number != null) {
			return BigDecimal.valueOf(number.doubleValue());
		}
		return null;
	}
	
	/**
	 * 如果输入字符串可以转成BigDecimal，返回转成的BigDecimal，否则返回BigDecimal.valueOf(0)。
	 * 
	 * @param value 要转换的字符串
	 * @return 如果成功，转换成的BigDecimal，否则BigDecimal.valueOf(0)
	 */
	public static BigDecimal toDecimalSafe(String value) {
		BigDecimal result = toDecimal(value);
		return result == null ? BigDecimal.valueOf(0) : result;
	}

	/**
	 * 如果supplier提供的字符串可以转成BigDecimal，返回转成的BigDecimal，否则返回BigDecimal.valueOf(0)。
	 * 
	 * @param supplier 提供需要转换的字符串
	 * @return 如果成功，转换成的BigDecimal，否则BigDecimal.valueOf(0)
	 */
	public static BigDecimal toDecimalSafe(Supplier<String> supplier) {
		return toDecimalSafe(supplier.get());
	}
	
	/**
	 * 如果decimal不是null，返回其字符串表示，否则返回null。
	 * 
	 * @param decimal 要转换的数
	 * @return 如果成功，decimal转成的字符串，否则null
	 */
	public static String fromDecimal(BigDecimal decimal) {
		return decimal == null ? null : decimal.toString();
	}
	
	/**
	 * 如果输入字符串可以转为Double，返回转成的Double，否则返回null。
	 * 
	 * @param value 要转换的字符串
	 * @return 如果成功，转换成的Double，否则null
	 */
	public static Double toDouble(String value) {
		Double result = null;
		if (isNotEmpty(value)) {
			try {
				result = Double.valueOf(value);
			} catch (Exception e) {
				// ignore
			}
		}
		return result;
	}
	
	/**
	 * 如果supplier提供的字符串可以转成Double，返回转成的Double，否则返回null。
	 * 
	 * @param supplier 提供要转换的字符串
	 * @return 如果成功，转换成的Double，否则null
	 */
	public static Double toDouble(Supplier<String> supplier) {
		return toDouble(supplier.get());
	}
	
	/**
	 * 如果输入字符串可以转为double，返回转成的double，否则返回0。
	 * 
	 * @param value 要转换的字符串
	 * @return 如果成功，转换成的double，否则0
	 */
	public static double toDoubleSafe(String value) {
		double result = 0;
		if (isNotEmpty(value)) {
			try {
				result = Double.parseDouble(value);
			} catch (Exception e) {
				// ignore
			}
		}
		return result;
	}
	
	/**
	 * 如果supplier提供的字符串可以转成double，返回转成的double，否则返回0。
	 * 
	 * @param supplier 提供要转换的字符串
	 * @return 如果成功，转换成的double，否则0
	 */
	public static double toDoubleSafe(Supplier<String> supplier) {
		return toDoubleSafe(supplier.get());
	}
	
	/**
	 * 如果d不是null，返回其字符串表示，否则返回null。
	 * 
	 * @param d 要转换的数
	 * @return 如果成功，d转成的字符串，否则null
	 */
	public static String fromDouble(Double d) {
		return d == null ? null : d.toString();
	}
	
}
